#include "jmeta.h"

namespace JXQ
{

JMeta::JMeta()
{

}

const JTypeInfo &JMeta::info(const std::string &typeName)
{
	size_t id = getTypeId(typeName);
	if( id > 0 )
	{
		auto it = JTypeInfo::typeInfoHash.find(id);
		if( it != JTypeInfo::typeInfoHash.end() )
			return *it->second;
	}
	return JTypeInfo::voidType;
}

void *JMeta::copyObject(size_t typeID, const void *beCopied)
{
	if( typeID == 0 )
		return nullptr;

	// 拷贝构造方法
	return callConstructMethod(JOtherMethodHash::findCopyConstructMethod(typeID),
							   beCopied);
}

bool JMeta::assignment(size_t typeID, void *src, const void *beCopied)
{
	if( typeID == 0 )
		return false;

	// 拷贝赋值方法
	auto func = JOtherMethodHash::findCopyMethod(typeID);
	if( func == nullptr )
		return false;

	func(src, beCopied);
	return true;
}

bool JMeta::deleteObject(size_t typeID, const void *obj)
{
	if( typeID == 0 )
		return false;

	// 析构方法
	auto &method = JOtherMethodHash::findDestructMethod(typeID);
	if( method == nullptr )
		return false;

	method(obj);
	return true;
}

size_t JMeta::getTypeId(const std::string &typeName)
{
	auto it = JTypeInfo::typeIdHash.find(typeName);
	if( it == JTypeInfo::typeIdHash.end() )
	{
		jError() << "The type is not register: name =" << typeName;
		return 0;
	}
	return it->second;
}

bool JMeta::isTypeRegister(size_t id)
{
	if( id > 0 )
	{
		auto it = JTypeInfo::typeInfoHash.find(id);
		return it != JTypeInfo::typeInfoHash.end();
	}
	return false;
}

size_t JMeta::verify(const std::string &typeName)
{
	if( typeName == "void" )
	{
		jError() << "JMeta::verify: the operation type is 'void'.";
		return false;
	}
	return getTypeId(typeName);
}

} //namespace JXQ
